﻿using NearAop.Interfaces;
using System;

namespace NearAop
{
    public abstract class MethodProxyBase : Attribute, IAop
    {
        public MethodProxyBase(Type proxyType) => ProxyType = proxyType;

        /// <summary>
        /// 代理类型
        /// </summary>
        public virtual Type ProxyType { get; protected set; }

        /// <summary>
        /// 代理类中处理函数名称(默认空)
        /// </summary>
        public virtual string HandlerName { get; set; }

    }


    /// <summary>
    /// 为进入函数和退出时提供切面代理
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
    public sealed class AddProxyMethodAttribute : MethodProxyBase
        , IAopProxyMethodOnEntry
        , IAopProxyMethodOnExit
    {

        /// <summary>
        /// 为进入函数和退出时提供切面代理
        /// </summary>
        /// <param name="proxyType">代理类型</param>
        public AddProxyMethodAttribute(Type proxyType) : base(proxyType) { }

        /// <summary>
        /// 是否在退出函数前收集参数值(默认关闭)
        /// </summary>
        public bool IsSetValueOnExit { get; set; }

        /// <summary>
        /// 是否更新参数值(默认关闭)
        /// </summary>
        public bool IsUpdateValue { get; set; }

        /// <summary>
        /// 全部启用(启用更新参数和退出获取参数值)
        /// </summary>
        public bool IsAllEnabled
        {
            get => IsUpdateValue & IsSetValueOnExit;
            set
            {
                IsUpdateValue = value;
                IsSetValueOnExit = value;
            }
        }

    }

    /// <summary>
    /// 为进入函数时提供切面代理
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
    public sealed class AddProxyMethodEntryAttribute : MethodProxyBase, IAopProxyMethodOnEntry
    {

        /// <summary>
        /// 为进入函数时提供切面代理
        /// </summary>
        /// <param name="proxyType">代理类型</param>
        public AddProxyMethodEntryAttribute(Type proxyType) : base(proxyType) { }

        /// <summary>
        /// 是否更新参数值(默认关闭)
        /// </summary>
        public bool IsUpdateValue { get; set; }

    }


    /// <summary>
    /// 为退出函数时提供切面代理
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
    public sealed class AddProxyMethodExitAttribute : MethodProxyBase, IAopProxyMethodOnExit
    {
        /// <summary>
        /// 为退出函数时提供切面代理
        /// </summary>
        /// <param name="proxyType">代理类型</param>
        public AddProxyMethodExitAttribute(Type proxyType) : base(proxyType) { }

        /// <summary>
        /// 是否在退出函数前收集参数值(默认关闭)
        /// </summary>
        public bool IsSetValueOnExit { get; set; }

    }
}
